import http from 'http';
import fs from 'fs';
import os from 'os';
import inquirer from 'inquirer';
import chalk from 'chalk';

// 默认配置
let targetIp = '1.95.79.30';
let PORT_RANGE_START = 3000;
let PORT_RANGE_END = 9000;
const BATCH_SIZE = 200;
let TIMEOUT = 2000;
const DELAY_BETWEEN_BATCHES = 500; // 每批扫描之间延迟 500ms

const args = process.argv.slice(2);
if (args[0]) targetIp = args[0];
if (args[1]) {
  const [start, end] = args[1].split('-').map(Number);
  if (!isNaN(start) && !isNaN(end)) {
    PORT_RANGE_START = start;
    PORT_RANGE_END = end;
  }
}

// 检查单个端口是否可通过HTTP访问
function checkPort(port) {
  return new Promise((resolve) => {
    const req = http.get(`http://${targetIp}:${port}`, (res) => {
      res.resume(); // 必须读取响应体以释放内存
      if (res.statusCode >= 200 && res.statusCode < 400) {
        resolve(port);
      } else {
        resolve(null);
      }
    });

    req.on('error', () => {
      resolve(null);
    });

    req.setTimeout(TIMEOUT, () => {
      req.abort();
      resolve(null);
    });
  });
}

// 批量扫描函数
async function scanPorts() {
  const openPorts = [];
  const allPorts = Array.from({ length: PORT_RANGE_END - PORT_RANGE_START + 1 }, (_, i) => PORT_RANGE_START + i);

  for (let i = 0; i < allPorts.length; i += BATCH_SIZE) {
    const batch = allPorts.slice(i, i + BATCH_SIZE);
    console.log(`🔍 扫描端口 ${batch[0]} - ${batch[batch.length - 1]}...`);

    const results = await Promise.allSettled(batch.map(port => checkPort(port)));

    results.forEach((result, idx) => {
      if (result.status === 'fulfilled' && result.value !== null) {
        console.log(`✅ 端口 ${batch[idx]} 可访问`);
        openPorts.push(batch[idx]);
      }
    });

    // 控制频率，防止触发防火墙
    await new Promise(resolve => setTimeout(resolve, DELAY_BETWEEN_BATCHES));
  }

  if(openPorts.length){
    console.log(chalk.blue('\n🎉 扫描完成，开放的 Web 端口有：'));
    
    console.log(openPorts);
  }else{
    console.log(chalk.red('\n❌ 未找到开放的 Web 端口'));
  }
  

  // 保存为 JSON 文件
  const outputJson = {
    ip: targetIp,
    openWebPorts: openPorts,
    scannedAt: new Date().toISOString()
  };

  fs.writeFileSync('open_web_ports.json', JSON.stringify(outputJson, null, 2));
  console.log('📄 结果已保存至 open_web_ports.json');

  // 保存为 CSV 文件
  const csvContent = ['Port'].concat(openPorts).join(os.EOL);
  fs.writeFileSync('open_web_ports.csv', csvContent);
  console.log('📄 结果已保存至 open_web_ports.csv');
}

export const scannerMain = () => {
  console.log('👏欢迎使用端口扫描工具🔧');
  console.log('检查某个端口是否可通过HTTP访问');

  inquirer.prompt([
    {
      type: 'input',
      name: 'host',
      message: '请输入要扫描的主机地址：',
      default: '192.168.0.1',
    },
    {
      type: 'number',
      name: 'portStart',
      message: '请输入要扫描的端口开始（如：3000）：',
      default: 3000,
      validate:(value)=>{
        if(value && value > 0){
          return true
        }else{
          return '请输入正确的端口号'
        }
      }
    },
    {
      type: 'input',
      name: 'portEnd',
      message: '请输入要扫描的端口结束（如：9000）：',
      default: 9000,
      validate:(value)=>{
        if(value && value > 0){
          return true
        }else{
          return '请输入正确的端口号'
        }
      }
    },
  ]).then(answers => { 
    targetIp = answers.host;
    PORT_RANGE_START = answers.portStart;
    PORT_RANGE_END = answers.portEnd;
    console.log(`🚀 开始扫描 ${targetIp}:${PORT_RANGE_START}-${PORT_RANGE_END} 范围的端口可访问性`);
    scanPorts();
  })
};